package team2.arsystem.DomainObjects;

import java.util.ArrayList;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import team2.arsystem.Database.DBMediator;
import team2.arsystem.Utilities.CommandConstants;
import team2.arsystem.Utilities.Validate;
import android.util.Log;


/*This class is responsible for actions related to the Account(like create account, add members , etc) but does not handle the credit and debit stuff. This again is a Singleton.*/
public class Account {

	private static String accountUserName="";
	private static String accountPassword="";
	private static Account accountObj=new Account();
	
	public static Account getAccountObj()
	{
	    return accountObj;
	}
	
	
	public String getAccountUserName()
	{
		return accountUserName;
	}
	
	private void setAccountUserName(String userName)
	{
		accountUserName = userName;
	}
	
	/* May be used when implementing Change password functionality.
	 * private String getAccountPassword()
	 
	{
		return accountPassword;
	}
	*/
	
	/*Login : Validates the arguments and checks if the login details exist in the database.*/
	public boolean login(String userName, String password)
	{
		boolean loginSuccess = false;
		
		try
		{
		if(Validate.validateUserName(userName))
    	{
    		if(Validate.validatePassword(password))
    		{
    			if(loginPermitted(userName,password))
    			{
    				Log.i("Login info", "Login Success");
    				loginSuccess = true;
    				setAccountUserName(userName);
    				accountPassword = password;
    			}
    			else
    			{
    				Log.i("Login error", "Username password does not match");
    				loginSuccess = false;
    			}
    		}
    		else
    		{
    			Log.i("Login error", "Invalid password");
    			loginSuccess = false;
    		}
    	}
    	else
    	{
    		Log.i("Login error", "Invalid user name");
    		loginSuccess = false;
    	}
		}
		catch(Exception e)
		{
			loginSuccess = false;
		}
		return loginSuccess;
	}
	  
	/*Create New Account 
	 * TODO : Check if the confirmPwd is the same as pwd in the GUI class itself.*/
	public boolean createNewAccount(String userName, String pwd, String confirmPwd, String securityQn, String securityAns)
	{
		boolean createAccountResult = false;
		try
		{
			if(!(pwd.equals(confirmPwd)))
			{
				createAccountResult = false;
				return createAccountResult;
			}
			
			if(Validate.validateUserName(userName))
			{
				if(Validate.validatePassword(pwd))
				{
					if(createAccount(userName,pwd,securityQn,securityAns))
					{
						Log.i("Status","Created the account successfully");
    					createAccountResult = true;
					}
					else
					{
						Log.i("Status","Creation of account was not successfull");
    	   				createAccountResult = false;
					}
				}
				else
				{
					Log.i("Status","Password does not match its criteria");
					createAccountResult = false;
				}
			}
			else
			{
				Log.i("Status","Username does not match its criteria");
				createAccountResult = false;
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			createAccountResult = false;
		}
		
		return createAccountResult;
	}
	  
	
	/*Adding a new member to the application: This added member will be a part of a transaction that the user may wish to enter.*/
	public boolean addNewMember(String firstName, String middleName, String lastName, String mobileNumber)
	{
		boolean addMemberSuccess = false;
		
		try
		{
			if(Validate.validateName(firstName,CommandConstants.nameMinLength))
			{
				if(Validate.validateName(middleName,CommandConstants.middleNameMinLength))
				{
					if(Validate.validateName(lastName,CommandConstants.nameMinLength))
					{
						if(Validate.validateMobileNumber(mobileNumber))
						{
							if(addMemberInDB(firstName,middleName,lastName,mobileNumber))
							{
								Log.i("Status", "Successfully added the member");
								addMemberSuccess = true;
							}
							else
							{
								Log.i("Status", "Failed adding the member");
								addMemberSuccess = false;
							}
						}
						else
						{
							Log.i("Status", "Invalid mobile number");
							addMemberSuccess = false;

						}
					}
					else
					{
						Log.i("Status", "Invalid last name");
						addMemberSuccess = false;

					}
				}
				else
				{
					Log.i("Status", "Invalid middle name");
					addMemberSuccess = false;
				}
			}
			else
			{
				Log.i("Status", "Invalid first name");
				addMemberSuccess = false;
			}
		}
		catch(Exception e)
		{
			addMemberSuccess = false;
			e.printStackTrace();
		}
		return addMemberSuccess;
	}
	
	/*Edit the details of an existing member.*/
	public boolean editMember(String firstName, String middleName, String lastName, String mobileNumber, String oldName, String oldMobileNumber)
	{
		boolean editMemberSuccess = false;
		
		try
		{
			if(Validate.validateName(firstName,CommandConstants.nameMinLength))
			{
				if(Validate.validateName(middleName,CommandConstants.middleNameMinLength))
				{
					if(Validate.validateName(lastName,CommandConstants.nameMinLength))
					{
						if(Validate.validateMobileNumber(mobileNumber))
						{
							if(editMemberInDB(firstName,middleName,lastName,mobileNumber,oldName,oldMobileNumber))
							{
								Log.i("Status", "Successfully edited the deails of the member");
								editMemberSuccess = true;
							}
							else
							{
								Log.i("Status", "Failed editing the details of the member");
								editMemberSuccess = false;
							}
						}
						else
						{
							Log.i("Status", "Invalid mobile number");
							editMemberSuccess = false;

						}
					}
					else
					{
						Log.i("Status", "Invalid last name");
						editMemberSuccess = false;

					}
				}
				else
				{
					Log.i("Status", "Invalid middle name");
					editMemberSuccess = false;
				}
			}
			else
			{
				Log.i("Status", "Invalid first name");
				editMemberSuccess = false;
			}
		}
		catch(Exception e)
		{
			editMemberSuccess = false;
			e.printStackTrace();
		}
		return editMemberSuccess;
	}
	
	
	/*Get the members added the user in this application. This will be used to populate the members field when the user tries to add a new transaction.*/
	public ArrayList<String> getMembers() throws Exception
	{
		ArrayList<String> members=null;
		try
		{
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.getMembers));
			nameValuePairs.add(new BasicNameValuePair("UserName",getAccountUserName()));
			
			DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONArray response = DBMediator.getResponseFromServerAsArray();
		    
		       if(!(response.getJSONObject(0).has("MemberCount")))
		       {
		    	   members = new ArrayList<String>();
		    		for(int i=0;i<response.length();i++){
		    		JSONObject json_data = response.getJSONObject(i);
					String name=json_data.getString("firstName") + " "+ json_data.getString("middleName") + " "+ json_data.getString("lastName"); 
				    members.add(name);
		       }
							
			}	
		    
		}
		catch(Exception e)
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			
		}
		return members;
	}
	
	/*Set the currency.*/
	public boolean setCurrency(String currency)
	{
		boolean IsCurrencySet = false;
		
		try
		{
			if(setCurrencyInDB(currency))
			{
				Log.i("Status", "Successfully set the currency");
				IsCurrencySet = true;
			}
			else
			{
				Log.i("Status", "Failed setting the currency");
				IsCurrencySet = false;
			}
		}
		catch(Exception e)
		{
			IsCurrencySet = false;
			e.printStackTrace();
		}
		return IsCurrencySet;
		
	}
	
	/*Get the members' details added by the user in this application. */
	public ArrayList<ArrayList<String>> viewMembers() throws Exception
	{
		
		ArrayList<String> members=new ArrayList<String>();
		ArrayList<String> mobileNumbers=new ArrayList<String>();
		
		
		try
		{
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.viewMembers));
			nameValuePairs.add(new BasicNameValuePair("UserName",getAccountUserName()));
			
			DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONArray response = DBMediator.getResponseFromServerAsArray();
		    
		       if(!(response.getJSONObject(0).has("MemberCount")))
		       {
		    	   members = new ArrayList<String>();
		    		for(int i=0;i<response.length();i++){
		    		JSONObject json_data = response.getJSONObject(i);
					String name=json_data.getString("firstName") + " "+ json_data.getString("middleName") + " "+ json_data.getString("lastName"); 
				   
					members.add(name);
					mobileNumbers.add(json_data.getString("mobileNumber"));
		       }
							
			}	
		    
		}
		catch(Exception e)
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			
		}
		
		ArrayList<ArrayList<String>> memberDetails = new ArrayList<ArrayList<String>>();
		memberDetails.add(members);
		memberDetails.add(mobileNumbers);
		
		return memberDetails;
	}
	
	
	/*For user logout, just clean up the variables.*/
	public boolean logout()
	{
		accountUserName = "";
		accountPassword = "";
		return true;
	}
	
	/*The following are the private helper methods in this class. They deal with handling information in the database. For this, do the following:
	 * Form the name value pairs, 
	 * send the request to server,
	 * get the response, 
	 * parse the response.*/
	private boolean loginPermitted(String user, String pwd) throws Exception
	{
		try {
			
			boolean loginPermitted = false;
			
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.loginUser));
			nameValuePairs.add(new BasicNameValuePair("UserName",user));
			nameValuePairs.add(new BasicNameValuePair("Password",pwd));
			
		    DBMediator.postHttpCommand(nameValuePairs);
		    
		    Log.i("Username", user);
		    Log.i("Password", pwd);
		    
		    JSONObject response = DBMediator.getResponseFromServerAsObject();
			if((response.getInt("UserCount"))==1)
				loginPermitted=true;
		
		  
		    return loginPermitted;
	    	
		}
		catch (Exception e) 
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	
	private boolean createAccount(String userName,String pwd,String securityQn,String securityAns) throws Exception
	{
		try {
			
			boolean accountCreated = false;
			
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.createNewAccount));
			nameValuePairs.add(new BasicNameValuePair("UserName",userName));
			nameValuePairs.add(new BasicNameValuePair("Password",pwd));
			nameValuePairs.add(new BasicNameValuePair("SecurityQn",securityQn));
			nameValuePairs.add(new BasicNameValuePair("SecurityAns",securityAns));
			
		    DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONObject response = DBMediator.getResponseFromServerAsObject();
		   
			if((response.getBoolean("UserAdded"))==true)
			{
				accountCreated=true;
				Log.i("User added","SUCCESS");
			}
		    return accountCreated;
	    	
		}
		catch (Exception e) 
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	private boolean addMemberInDB(String firstName, String middleName, String lastName, String mobileNumber) throws Exception
	{
		try {
			
			boolean memberAdded = false;
			
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.addNewMember));
			nameValuePairs.add(new BasicNameValuePair("UserName",getAccountUserName()));
			nameValuePairs.add(new BasicNameValuePair("FirstName",firstName));
			nameValuePairs.add(new BasicNameValuePair("MiddleName",middleName));
			nameValuePairs.add(new BasicNameValuePair("LastName",lastName));
			nameValuePairs.add(new BasicNameValuePair("MobileNumber",mobileNumber));
			
			DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONObject response = DBMediator.getResponseFromServerAsObject();
		   
			if((response.getBoolean("MemberAdded"))==true)
			{
				memberAdded=true;
				Log.i("Member added","SUCCESS");
			}
			
		 
		    return memberAdded;
	    	
		}
		catch (Exception e) 
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	private boolean editMemberInDB(String firstName, String middleName, String lastName, String mobileNumber, String oldName, String oldMobileNumber) throws Exception
	{
		try {
			
			boolean memberEdited = false;
			
			String oldFirstName = oldName.substring(0,oldName.indexOf(' '));
			oldName=oldName.substring(oldName.indexOf(' ')+1);
			String oldMiddleName = oldName.substring(0,oldName.indexOf(' ')); ;
			oldName=oldName.substring(oldName.indexOf(' ')+1);
			String oldLastName = oldName;
			
			Log.i("old name : ", oldFirstName+ ","+ oldMiddleName+","+oldLastName);
			
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.editMember));
			nameValuePairs.add(new BasicNameValuePair("UserName",getAccountUserName()));
			nameValuePairs.add(new BasicNameValuePair("FirstName",firstName));
			nameValuePairs.add(new BasicNameValuePair("MiddleName",middleName));
			nameValuePairs.add(new BasicNameValuePair("LastName",lastName));
			nameValuePairs.add(new BasicNameValuePair("MobileNumber",mobileNumber));
			nameValuePairs.add(new BasicNameValuePair("OldFirstName",oldFirstName));
			nameValuePairs.add(new BasicNameValuePair("OldMiddleName",oldMiddleName));
			nameValuePairs.add(new BasicNameValuePair("OldLastName",oldLastName));
			nameValuePairs.add(new BasicNameValuePair("OldMobileNumber",oldMobileNumber));
			
			DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONObject response = DBMediator.getResponseFromServerAsObject();
		   
			if((response.getBoolean("MemberEdited"))==true)
			{
				memberEdited=true;
				Log.i("Member edited","SUCCESS");
			}
			
		 
		    return memberEdited;
	    	
		}
		catch (Exception e) 
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			return false;
		}
	}
	
	private boolean setCurrencyInDB(String currency) throws Exception
	{
		try {
			
			boolean currencyAdded = false;
			
		    ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			nameValuePairs.add(new BasicNameValuePair("command",CommandConstants.setCurrency));
			nameValuePairs.add(new BasicNameValuePair("UserName",getAccountUserName()));
			nameValuePairs.add(new BasicNameValuePair("Currency",currency));
			
			
			DBMediator.postHttpCommand(nameValuePairs);
		    
		    JSONObject response = DBMediator.getResponseFromServerAsObject();
		   
			if((response.getBoolean("CurrencySet"))==true)
			{
				currencyAdded=true;
				Log.i("Set currency","SUCCESS");
			}
			
		 
		    return currencyAdded;
	    	
		}
		catch (Exception e) 
		{
			Log.i("errorrrr",e.getMessage());
			e.printStackTrace();
			return false;
		}
	}

	
}
